package com.fbs.job.admin.core.thread;
import com.fbs.job.admin.core.config.FbsJobAdminConfig;
import com.fbs.job.admin.core.entity.FbsJobLogReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class JobLogReportHelper  {
    private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class);
    private static JobLogReportHelper instance = new JobLogReportHelper();
    public static JobLogReportHelper getInstance(){
        return instance;
    }


    private Thread logReportThread;
    private volatile boolean toStop = false;

    public void start(){
        logReportThread = new Thread(new Runnable() {
            @Override
            public void run() {
                 while (!toStop){
                     // last clean log time
                     long lastCleanLogTime = 0;
                     try {
                         for (int i = 0; i < 3; i++) {

                             // today
                             Calendar itemDay = Calendar.getInstance();
                             itemDay.add(Calendar.DAY_OF_MONTH, -i);
                             itemDay.set(Calendar.HOUR_OF_DAY, 0);
                             itemDay.set(Calendar.MINUTE, 0);
                             itemDay.set(Calendar.SECOND, 0);
                             itemDay.set(Calendar.MILLISECOND, 0);

                             Date todayFrom = itemDay.getTime();

                             itemDay.set(Calendar.HOUR_OF_DAY, 23);
                             itemDay.set(Calendar.MINUTE, 59);
                             itemDay.set(Calendar.SECOND, 59);
                             itemDay.set(Calendar.MILLISECOND, 999);

                             Date todayTo = itemDay.getTime();
                             // refresh log-report every minute
                             FbsJobLogReport fbsJobLogReport = new FbsJobLogReport();
                             fbsJobLogReport.setTriggerDay(todayFrom);
                             fbsJobLogReport.setRunningCount(0);
                             fbsJobLogReport.setSucCount(0);
                             fbsJobLogReport.setFailCount(0);

                             Map<String, Object> triggerCountMap = FbsJobAdminConfig.getAdminConfig().getFbsJobLogMapper().findLogReport(todayFrom, todayTo);
                             if (triggerCountMap!=null && triggerCountMap.size()>0) {
                                 int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0;
                                 int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0;
                                 int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0;
                                 int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;

                                 fbsJobLogReport.setRunningCount(triggerDayCountRunning);
                                 fbsJobLogReport.setSucCount(triggerDayCountSuc);
                                 fbsJobLogReport.setFailCount(triggerDayCountFail);
                             }

                             // do refresh
                             int ret = FbsJobAdminConfig.getAdminConfig().getFbsJobLogReportMapper().update(fbsJobLogReport);
                             if (ret < 1) {
                                 FbsJobAdminConfig.getAdminConfig().getFbsJobLogReportMapper().save(fbsJobLogReport);
                             }
                         }
                     }catch (Exception e){
                         if (!toStop) {
                             logger.error(">>>>>>>>>>> fbs-job, job log report thread error:{}", e);
                         }
                     }


                    if (FbsJobAdminConfig.getAdminConfig().getLogretentiondays()>0
                            && System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000){
                        // expire-time
                        Calendar expiredDay = Calendar.getInstance();
                        expiredDay.add(Calendar.DAY_OF_MONTH, -1 * FbsJobAdminConfig.getAdminConfig().getLogretentiondays());
                        expiredDay.set(Calendar.HOUR_OF_DAY, 0);
                        expiredDay.set(Calendar.MINUTE, 0);
                        expiredDay.set(Calendar.SECOND, 0);
                        expiredDay.set(Calendar.MILLISECOND, 0);
                        Date clearBeforeTime = expiredDay.getTime();


                        // clean expired log
                        List<Long> logIds = null;
                        do {
                            logIds = FbsJobAdminConfig.getAdminConfig().getFbsJobLogMapper().findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
                            if (logIds!=null && logIds.size()>0) {
                                FbsJobAdminConfig.getAdminConfig().getFbsJobLogMapper().clearLog(logIds);
                            }
                        } while (logIds!=null && logIds.size()>0);
                    }
                     try {
                         TimeUnit.MINUTES.sleep(1);
                     } catch (Exception e) {
                         if (!toStop) {
                             logger.error(e.getMessage(), e);
                         }
                     }



                 }
            }
        });

        logReportThread.setDaemon(true);
        logReportThread.setName("fbs-job, admin JobLogReportHelper");
        logReportThread.start();

    }

    public void toStop(){
        toStop = true;
        logReportThread.interrupt();
        try {
            logReportThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
